# 缓存

Midscene 支持缓存 Plan 的步骤与匹配到的 DOM 元素信息，减少 AI 模型的调用次数，从而大幅提升执行效率。

Android 自动化任务支持 planning 缓存，但不支持元素定位缓存（因为没有 XPath 支持）。

**效果**

通过引入缓存后，用例的执行时间大幅降低了，例如在如下案例中，执行耗时从51秒降低到了28秒。

* **before**

![](/cache/no-cache-time.png)

* **after**

![](/cache/use-cache-time.png)

## 使用方式

想要启用缓存特性，有两个关键点：

1. 设置 `MIDSCENE_CACHE=1` 环境变量，用以启用缓存匹配
2. 设置 `cacheId` 来指定缓存文件名。在 Playwright 和 Yaml 模式下，`cacheId` 会自动设置为测试文件名，在 Javascript Agent 模式下，需要手动设置 `cacheId`。

### Playwright

在集成 Playwright 时，可以通过设置 `MIDSCENE_CACHE=1` 环境变量来启用缓存匹配。

`cacheId` 会自动设置为测试文件名。

```diff
- playwright test --config=playwright.config.ts
+ MIDSCENE_CACHE=1 playwright test --config=playwright.config.ts
```

### Javascript Agent, 例如 PuppeteerAgent, AgentOverChromeBridge

在 Javascript agent 模式下，需要手动设置 `cacheId` 来指定缓存标识。
同时，通过设置 `MIDSCENE_CACHE=1` 环境变量来启用缓存匹配。

```diff
- tsx demo.ts 
+ MIDSCENE_CACHE=1 tsx demo.ts
```

```javascript
const mid = new PuppeteerAgent(originPage, {
  cacheId: 'puppeteer-swag-sab', // 增加缓存标识
});
```

### Yaml

在 Yaml 模式下，需要通过设置 `MIDSCENE_CACHE=1` 环境变量来启用缓存匹配。

`cacheId` 会自动设置为 yaml 文件名。

```diff
- npx midscene ./bing-search.yaml
+ # 增加缓存标识, cacheId 为 yaml 文件名
+ MIDSCENE_CACHE=1 npx midscene ./bing-search.yaml
```

## 缓存策略

缓存内容会保存到 `./midscene_run/cache` 目录下，以 `.cache.yaml` 为扩展名。

缓存内容分为两类：

1. 任务规划结果，例如 `ai` 和 `aiAction` 方法的结果
2. 元素定位后的 XPath 数据，例如 `.aiLocate`, `.aiTap` 等方法的结果

查询类方法，例如 `aiBoolean`, `aiQuery`, `aiAssert` 的内容不会被缓存。

如果缓存未命中，Midscene 将会重新调用 AI 模型，并更新缓存文件。

## 常见问题

### 没有生成缓存文件

请确认你在构造函数中设置了 `cacheId`。

### 如何检查缓存是否命中？

你可以查看报告文件。如果缓存命中，你将看到 `cache` 提示，并且执行时间大幅降低。

### 为什么在 CI 中无法命中缓存？

你需要在 CI 中将缓存文件提交到仓库中，并再次检查缓存命中的条件。

### 如果有了缓存，是否就不需要 AI 服务了？

不是的。

缓存是加速脚本执行的手段，但它不是确保脚本长期稳定执行的工具。我们注意到，当页面发生变化时，缓存可能会失效（例如当元素 DOM 结构发生变化时）。在缓存失效时，Midscene 仍然需要调用 AI 服务来重新执行任务。

### 如何手动删除缓存？

你可以删除 `./midscene_run/cache` 目录中的缓存文件，或者编辑缓存文件的内容。

### 如果我想禁用单个 API 的缓存，怎么办？

你可以使用 `cacheable` 选项来禁用单个 API 的缓存。

具体用法请参考对应 [API](./api.mdx) 的文档。

### 使用 XPath 缓存元素定位信息的局限性

Midscene 使用 [XPath](https://developer.mozilla.org/en-US/docs/Web/XML/XPath) 来缓存元素定位信息。我们使用相对严格的策略来防止误匹配。在以下情况下，缓存不会命中：

1. 新元素在相同的 XPath 下的文本内容与缓存元素不同。
2. 页面的 DOM 结构与缓存时的结构不同。

当缓存未命中时，Midscene 将回退到继续使用 AI 服务来查找元素。

### 获取缓存相关的调试日志

在环境变量中配置 `DEBUG=midscene:cache:*`，你可以看到缓存相关的调试日志。
